<?php

/**
 * Clase que carga informaci�n de un archivo
 */
class LoadFile {
  var $bolPosibleCargaTotal;
  var $strArchivoFuente    ;
  var $intCantidadColumnas ;
  var $arrLineasLeidas     ;
  var $arrLineasPosibles   ;
  var $intIndiceActual     ;
  var $arrSaltarSiExistenEnPrimeraFila;
  
  var $__arrErroresCarga;
  var $__arrInfoCarga   ;
  
  /**
   * Los tipos de chequeo son los siguientes:
   * 
   * N => Numero
   * Q => Entero
   * D => Fecha
   * S => Cadena
   * 
   * Si el tipo es seguido por un guion, el campo puede venir vacio, pero no puede ser un campo errado
   */
  var $arrTiposChequeo     ;
  
  var $EOF;
  var $__arrLineaActual;

  /**
   * Función que obtiene los datos para que el objeto pueda trabajar.
   *
   * @param String $strArchivoFuente                Nombre del archivo fuente a utilizar
   * @param Array  $arrTiposChequeo                 Arreglo con el tipo de cada columna para checar que sea valida.
   * @param int    $intCantidadColumnas             Numero de columnas que contendrá el archivo.
   * @param Array  $arrSaltarSiExistenEnPrimeraFila Arreglo que contiene los datos que se checarán en la primera columna. Si el valor de una linea en la primer columna contiene alguno de estos datos, se saltará y no será tomado en cuenta.
   */
  function __ArmarDatosPrivados($strArchivoFuente, $arrTiposChequeo, $intCantidadColumnas, $arrSaltarSiExistenEnPrimeraFila = "") {
    $this->bolPosibleCargaTotal = true;
    $this->strArchivoFuente     = $strArchivoFuente;
    $this->EOF                  = true;
    $this->arrTiposChequeo      = $arrTiposChequeo;
    $this->intCantidadColumnas  = $intCantidadColumnas;
    
    $this->__arrErroresCarga    = array();
    $this->arrLineasLeidas      = array();
    $this->arrLineasPosibles    = array();
    
    $this->arrSaltarSiExistenEnPrimeraFila = (is_array($arrSaltarSiExistenEnPrimeraFila) ? $arrSaltarSiExistenEnPrimeraFila : array());
    
    $this->__AbrirArchivo();
  }

  /**
   * Función que leé el archivo completo
   */
  function LeerCompleto() {
    error_reporting(E_ALL);
    set_time_limit(180);
    while(!$this->EOF) {
      $this->LineaCorrecta();
    }
  }
  
  /**
   * Se checa el contenido del arreglo $this->__arrLineaActual, que contiene
   * (sorpresa sorpresa) la linea actual
   * 
   * @return boolean verdadero si para el chequeo, false si no lo pasa
   */
  function __OtroChequeo() {
    return true;
  }
  
  /**
   * Función que intenta leer la siguiente linea en el archivo.
   * 
   * @return Boolean resultado de la lectura de la linea (False si no se pudo)
   */
  function LineaCorrecta() {
    $locDebug = false;
    $this->__ObtenerSiguienteLinea();
    
    if($this->EOF) {
      if($locDebug) { echo "Se encontro EOF<br>\n"; }
      return false;
    }
    
    foreach($this->arrSaltarSiExistenEnPrimeraFila as $strExcepcion) {
      if(Variables::DeepTrim($this->__arrLineaActual[0]) == $strExcepcion) {
        if($locDebug) { echo "Linea para saltar<br>\n"; }
        return false;
      }
    }
    
    if(!$this->__OtroChequeo()) {
      if($locDebug) { echo "No pasa otro chequeo<br>\n"; }
      $this->__arrErroresCarga[] = "Linea {$this->intIndiceActual}: No paso otro chequeo";
      return false;
    }

    if($this->intCantidadColumnas > 0) {
      if(($this->intCantidadColumnas != count($this->__arrLineaActual)) && ($this->intCantidadColumnas > count($this->__arrLineaActual))) {
        $this->bolPosibleCargaTotal = false;
//        $this->arrLineasPosibles [] = false;
        $this->arrLineasPosibles [] = 0;
        $this->arrLineasLeidas   [] = $this->__arrLineaActual;
        if($locDebug) { echo "Cantidad de lineas incorrecta (" . $this->intCantidadColumnas . " != " . count($this->__arrLineaActual) . "<br>\n"; }
        $this->__arrErroresCarga[] = "Linea {$this->intIndiceActual}: Cantidad de lineas incorrecta (" . $this->intCantidadColumnas . " != " . count($this->__arrLineaActual);
        return false;
      }
    }
    
    foreach($this->arrTiposChequeo as $i => $strTipoChequeo) {
      $strTipo = substr($strTipoChequeo, 0, 1);
      $strMod  = substr($strTipoChequeo, 1);
      
      if(!isset($this->__arrLineaActual[$i])) {
        $this->__arrLineaActual[$i] = "";
      }
      
      if(($strMod == "-") && (Variables::DeepTrim($this->__arrLineaActual[$i]) == "-") && ($strTipo == 'D')) {
        $this->__arrLineaActual[$i] = '';
      }

      if($strTipo == 'N') {
        $this->__arrLineaActual[$i] = str_replace(',', '', $this->__arrLineaActual[$i]);
      }
      
      if(($strMod == "-") && ($this->__arrLineaActual[$i] == "")) {
      } else {
        switch($strTipo) {
          case 'N':
            if(!is_numeric($this->__arrLineaActual[$i])) {
              $this->bolPosibleCargaTotal = false;
//              $this->arrLineasPosibles [] = false;
              $this->arrLineasPosibles [] = 0;
              $this->arrLineasLeidas   [] = $this->__arrLineaActual;
              if($locDebug) { echo "Linea {$this->intIndiceActual} ($i - {$this->__arrInfoCarga[$i]}): {$this->__arrLineaActual[$i]} no es un numero<br>\n"; }
              unset($this->arrInfoArchivoCVS);
              unset($this->arrInfoExtra);
              prent_r($this);
              $this->__arrErroresCarga[] = "Linea {$this->intIndiceActual} ($i - {$this->__arrInfoCarga[$i]}): {$this->__arrLineaActual[$i]} no es un numero";
              return false;
            }
            break;
          case 'Q':
            if((!is_numeric($this->__arrLineaActual[$i])) || (!is_integer($this->__arrLineaActual[$i] - 0))) {
              $this->bolPosibleCargaTotal = false;
//              $this->arrLineasPosibles [] = false;
              $this->arrLineasPosibles [] = 0;
              $this->arrLineasLeidas   [] = $this->__arrLineaActual;
              if($locDebug) { echo "Linea {$this->intIndiceActual} ($i - {$this->__arrInfoCarga[$i]}): {$this->__arrLineaActual[$i]} no es un entero<br>\n"; }
              $this->__arrErroresCarga[] = "Linea {$this->intIndiceActual} ($i - {$this->__arrInfoCarga[$i]}): {$this->__arrLineaActual[$i]} no es un entero";
              return false;
            }
            break;
          case 'D':
//            echo $this->__arrLineaActual[$i] . "<br>\n";
            $this->__arrLineaActual[$i] = Variables::DeepTrim($this->__arrLineaActual[$i]);
            if(strlen($this->__arrLineaActual[$i]) == 8) {
              $this->__arrLineaActual[$i] = substr($this->__arrLineaActual[$i], 0, 2) . "-" . substr($this->__arrLineaActual[$i], 3, 2) . "-20" . substr($this->__arrLineaActual[$i], 6, 2);
            } else if(strlen($this->__arrLineaActual[$i]) > 10) {
              $this->__arrLineaActual[$i] = substr($this->__arrLineaActual[$i], 0, 10);
            }
            $this->__arrLineaActual[$i] = Variables::NormalizeDate($this->__arrLineaActual[$i]);
            $unxFecha = strtotime($this->__arrLineaActual[$i]);
            if(($unxFecha === false) || ($unxFecha === -1)) {
              $this->bolPosibleCargaTotal = false;
//              $this->arrLineasPosibles [] = false;
              $this->arrLineasPosibles [] = 0;
              $this->arrLineasLeidas   [] = $this->__arrLineaActual;
              if($locDebug) { echo "Linea {$this->intIndiceActual} ($i - {$this->__arrInfoCarga[$i]}): {$this->__arrLineaActual[$i]} no es una fecha ($i)<br>\n"; }
              $this->__arrErroresCarga[] = "Linea {$this->intIndiceActual} ($i - {$this->__arrInfoCarga[$i]}): {$this->__arrLineaActual[$i]} no es una fecha";
              return false;
            }
            break;
          case 'S': default:
            if($this->__arrLineaActual[$i] == "") {
              $this->bolPosibleCargaTotal = false;
//              $this->arrLineasPosibles [] = false;
              $this->arrLineasPosibles [] = 0;
              $this->arrLineasLeidas   [] = $this->__arrLineaActual;
              if($locDebug) { echo "Linea {$this->intIndiceActual} ($i - {$this->__arrInfoCarga[$i]}): '{$this->__arrLineaActual[$i]}' no es una cadena<br>\n"; }
              $this->__arrErroresCarga[] = "Linea {$this->intIndiceActual} ($i - {$this->__arrInfoCarga[$i]}): {$this->__arrLineaActual[$i]} no es una cadena";
              return false;
            }
            break;
        }
      }
    }
    
//    $this->arrLineasPosibles[] = true;
    $this->arrLineasPosibles[] = 1;
    $this->arrLineasLeidas  [] = $this->__arrLineaActual;
    if(isset($this->__arrInfoExtraAct)) {
       $this->arrInfoExtra  [] = $this->__arrInfoExtraAct;
    }
    return true;
  }

  /**
   * Función que abre el archivo
   */
  function __AbrirArchivo() {
    echo "Funcion AbrirArchivo debe ser sobrecargada en el objeto destino<br />";
    echo "Debe cargar un archivo y establecer un estad donde pueda seguir leyendo el contenido<br />";
  }

  /**
   * Función que obtiene la siguiente linea del archivo
   */
  function __ObtenerSiguienteLinea() {
    echo "Funcion ObtenerSiguienteLinea debe ser sobrecargada en el objeto destino<br />";
    echo "Debe regresar un arreglo con la linea leida, poner ese arreglo en la variable __arrLineaActual y posicionarse en el siguiente renglon, poniendo EOF a verdadero o falso segun corresponda<br />";
  }
  
}

?>